#pragma once

#ifndef Uses_h
#define Uses_h

#include "Standards.h"
#include "StmtTable.h"
#include "VarTable.h"
#include "ProcTable.h"
#include "Schema.h"

class Uses {
	public:
		unordered_multimap<INDEX, INDEX> usesTableStmt;
		unordered_multimap<INDEX,set<INDEX>> usesTableProc;
		StmtTable* myST;
		VarTable* myVT;
		ProcTable* myPT;

		//! Constructor (takes in the VarTable, stmtTable and ProcTable)
		Uses(VarTable*, StmtTable*, ProcTable*);
		
		/*! 
		  A method that returns a set of statements that uses the statement in question
		  \param INDEX statement in question
		*/
		INDEX_SET getUsedIndexUses(INDEX);
	
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses(s,v)
		  \param DESIGN_ENTITY design-entity of s
		  \param NAME s
		  \param NAME v
		*/
		Schema getSynSyn(DESIGN_ENTITY, NAME, NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses(s,"x")
		  \param DESIGN_ENTITY design-entity of s
		  \param NAME s
		  \param string "x"
		*/
		Schema getSynIdent(DESIGN_ENTITY,NAME,string);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses(s,_)
		  \param DESIGN_ENTITY design-entity of s
		  \param NAME s
		*/
		Schema getSynUnd(DESIGN_ENTITY,NAME);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses(3,v)
		  \param INDEX 3
		  \param NAME v
		*/
		Schema getIntSyn(INDEX,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses(3,"x")
		  \param INDEX 3
		  \param string "x"
		*/
		Schema getIntIdent(INDEX,string);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses(3,_)
		  \param INDEX 3
		*/
		Schema getIntUnd(INDEX);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses("Solo","x")
		  \param string "Solo"
		  \param string "x"
		*/
		Schema getIdentIdent(string,string);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses("Solo",v)
		  \param string "Solo"
		  \param NAME v
		*/
		Schema getIdentSyn(string,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Uses("Solo",_)
		  \param string "Solo"
		*/
		Schema getIdentUnd(string);

		/*! 
		  A method that prints uses table for stmt
		*/
		void printAllStmt();
		
		/*! 
		  A method that prints uses table for proc
		*/
		void printAllProc();
		
		/*! 
		  A method that inserts tuple <x,y> into Uses table signifying x uses y
		  \param INDEX User (stmt)
		  \param INDEX Used (variable)
		*/
		void setUsesStmtUses(INDEX, INDEX);
		
		/*! 
		  A method that inserts tuple <x,y> into Uses table signifying x uses y
		  \param INDEX User (proc)
		  \param INDEX Used (variable)
		*/
		void setUsesProcUses(INDEX, INDEX);

	private:
		INDEX usesCount;
};

#endif